import proto from "../../proto/proto";
import { dbFunc } from "../../database/DateBaseFunc";
import { LobbyPlayerMgr } from "./player/LobbyPlayerMgr";
import { LobbyPlayer } from "./player/LobbyPlayer";
import { Protocol } from "../../proto/msg";
import { ClientServer, InnerMsg, InnerServer } from "../../socket/ClientServer";
import { ClientConnection, ConnectCloseReason } from "../../socket/connection/ClientConnection";
import { G2L_Check_Room, G2L_Match_Room, InnerProtocol, L2G_Check_Room, L2G_Match_Room } from "../../proto/innerMsg";

/**
 * lobby服务器
 */
export class LobbyServer extends ClientServer {
    playerMgr: LobbyPlayerMgr = new LobbyPlayerMgr();

    onClose(connection: ClientConnection): void {
        // //大厅断线删除玩家
        this.playerMgr.deletePlayer(connection)
    }

    /**
     * 接收客户端的消息
     * @param connection 客户端连接
     * @param cmd      消息id
     * @param reqWrap    消息包裹数据
     * @param body       主体数据 
     */
    onMsg(connection: ClientConnection, cmd: number, reqWrap: proto.ReqWrap, reqData: any): void {
        switch (cmd) {
            case Protocol.GAME_REGISTER: // 注册账号
                this.onRegister(connection, cmd, reqWrap, reqData)
                break;
            case Protocol.GAME_LOGIN: // 登录
                this.onLogin(connection, cmd, reqWrap, reqData)
                break;
            case Protocol.GAME_MATCH_ROOM: // 匹配房间
                this.onMatchRoom(connection, cmd, reqWrap, reqData)
                break;
            default:
                break;
        }
    }

    /**
     * 接收内部消息
     */
    onInnerMsg(cmd: number, data: InnerMsg, reply: (body?: any) => void): void {

    }

    /**
     * 接收内部推送消息
     */
    onPushInnerMsg(cmd: number, data: InnerMsg): void {

    }

    /**
     * 设置有效连接
     */
    private _setValidConnection(connection: ClientConnection, userId: number) {
        const player = new LobbyPlayer(userId);
        player.setConnection(connection);
        this.playerMgr.setPlayer(player)
        //检查连接,关闭被挤号玩家
        const userOtherConnections = this.getUserOnlineConnections(connection);
        userOtherConnections.forEach(otherConnection => {
            otherConnection.pushData(Protocol.PUSH_LOGIN_OTHER)
            this.deleteConnection(otherConnection, ConnectCloseReason.squeezed, 5)
        })
    }

    /**
     * 玩家注册
     */
    async onRegister(connection: ClientConnection, cmd: number, reqWrap: proto.ReqWrap, reqData: any) {
        const data = reqData as proto.Login
        const result = await dbFunc.register(data.account, data.password)
        let code = proto.CODE.DEFAULT
        if (result.errorcode == 0) {
            code = proto.CODE.SUCCESS
            this._setValidConnection(connection, result.userid);
        }
        connection.sendData(cmd, reqWrap, code, { userid: result.userid, nickname: result.nickname });
    }

    /**
     * 玩家登录
     */
    async onLogin(connection: ClientConnection, cmd: number, reqWrap: proto.ReqWrap, reqData: any) {
        const data = reqData as proto.Login
        const result = await dbFunc.login(data.account, data.password)
        let code = proto.CODE.DEFAULT
        if (result.errorcode == 0) {
            code = proto.CODE.SUCCESS
            this._setValidConnection(connection, result.userid);
        }

        const innerBody = new L2G_Check_Room()
        innerBody.userId = connection.userId
        this.sendInnerMsg(InnerProtocol.CHECK_ROOM, innerBody, InnerServer.GAME, (innerMsgId: number, data: InnerMsg) => {
            const body = data.body as G2L_Check_Room
            const respData = new proto.LoginResp()
            respData.userBaseInfo = new proto.UserBaseInfo()
            respData.userBaseInfo.userId = result.userid
            reqData.nickname = result.nickname

            respData.roomInfo = new proto.Room()
            respData.roomInfo.roomId = body.roomId
            respData.roomInfo.kindId = body.kindId

            // 返回登录成功
            connection.sendData(cmd, reqWrap, code, respData);
        })
    }

    /**
     * 匹配房间
     */
    onMatchRoom(connection: ClientConnection, cmd: number, reqWrap: proto.ReqWrap, reqData: any) {
        const kind = reqData as proto.Kind
        const innerBody = new L2G_Match_Room()
        innerBody.userId = connection.userId
        innerBody.kindId = kind.kindId
        console.log(`匹配房间---userid:${connection.userId},kindid:${kind.kindId}`);
        this.sendInnerMsg(InnerProtocol.MATCH_ROOM, innerBody, InnerServer.GAME, async (innerMsgId: number, data: InnerMsg) => {
            const body = data.body as G2L_Match_Room
            connection.sendData(cmd, reqWrap, proto.CODE.SUCCESS, { roomId: body.roomId, kindId: kind.kindId })
        })
    }
}


